package com.wangjiacai.utils.web.service.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.wangjiacai.utils.web.service.RedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

/*
 * @auther: wangjiacai
 *
 * @create: 2018-04-28 15:17:49
 */
@Service
@ConditionalOnProperty(value = "wangjiacai.redis",havingValue = "redis",matchIfMissing = true)
public class RedisServiceImpl implements RedisService {

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private ObjectMapper objectMapper;

    /**
     * 一周有多少秒
     */
    private static final int expire =   7*24* 60 * 60;

    /**
     * 将 key，value 存放到redis数据库中，默认设置过期时间为一周
     *
     * @param key
     * @param value
     */
    public void set(String key, Object value)  {
        try {
            redisTemplate.opsForValue().set(key, objectMapper.writeValueAsString(value));
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
    }

    public void hashSet(String key, Object hk,Object value)  {
        try {
            redisTemplate.opsForHash().put(key,objectMapper.writeValueAsString(hk),objectMapper.writeValueAsString(value));
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
    }

    /**
     * 将 key，value 存放到redis数据库中，设置过期时间单位是秒
     *
     * @param key
     * @param value
     * @param expireTime
     */
    public void set(String key, Object value, long expireTime){
        try {
            redisTemplate.opsForValue().set(key, objectMapper.writeValueAsString(value), expireTime, TimeUnit.SECONDS);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
    }

    /**
     * 判断 key 是否在 redis 数据库中
     *
     * @param key
     * @return
     */
    public boolean exists(final String key) {
        return redisTemplate.hasKey(key);
    }

    /**
     * 获取与 key 对应的对象
     * @param key
     * @param clazz 目标对象类型
     * @param <T>
     * @return
     */
    public <T> T get(String key, Class<T> clazz){
        String s = get(key);
        if (s == null) return null;
        try {
            return objectMapper.readValue(s,clazz);
        } catch (IOException e) {
            return null;
        }
    }

    public <T> T hashGet(String key, Object hk,Class<T> clazz)  {
        String value=hashGet(key,hk);
        if(value==null) return null;
        try {
            return objectMapper.readValue(value,clazz);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获取 key 对应的字符串
     * @param key
     * @return
     */
    public String get(String key) {
        if(key==null) return null;
        return redisTemplate.opsForValue().get(key);
    }

    public String hashGet(String key, Object hk)  {
        if(key==null||hk==null) return null;
        try {
            return (String) redisTemplate.opsForHash().get(key,objectMapper.writeValueAsString(hk));
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return null;
    }
    /**
     * 删除 key 对应的 value
     * @param key
     */
    public boolean delete(String key) {
        return redisTemplate.delete(key);
    }

    @Override
    public long hashDelete(String key, Object hk) {
        return redisTemplate.opsForHash().delete(key,hk);
    }

    public int getExpire(){
        return expire;
    }

    @Override
    public void set(String key, String value) {
        redisTemplate.opsForValue().set(key, value);
        if(get(key)==null) set(key,value);
    }

    @Override
    public void set(String key, String value, long expireTime) {
        redisTemplate.opsForValue().set(key, value, expireTime, TimeUnit.SECONDS);
        if(get(key)==null) set(key,value,expireTime);
    }
}
